import json
import re
import datetime
from datetime import timezone
import logging

from django.conf import settings
from django.core.paginator import Paginator
from django.db.models import Q

from fdfs_client.client import Fdfs_client

from Lovehome_Max_Shanghai.utils.Loginmixin import LoginMixin
from leisurely.utils import get_house_count_date

logger = logging.getLogger('django')
from django.http import JsonResponse
from django.views import View

from six_it.models import Order, House, Area, Facility, HouseImage


class ReleaseHousesView(View):
    '''发布房源'''

    def get(self, request):

        # 获取前端数据
        aid = request.GET.get('aid')
        sd = request.GET.get('sd')
        ed = request.GET.get('ed')
        # 排序方式
        sk = request.GET.get('sk')
        p = request.GET.get('p', default=1)

        # 获取用户
        user = request.user
        # 筛选条件
        filters = {}

        # 排序
        sk_dict = {'booking': "-order_count", "price-inc": "price", "price-des": "-price"}
        # 判断地区id
        if aid:
            filters["area"] = aid
        # # 判断时间
        # try:
        #     # 开始和结束时间都存在
        #     if sd and ed:
        #         start_date = datetime.datetime.strptime(sd, '%Y-%m-%d')
        #         end_date = datetime.datetime.strptime(ed, '%Y-%m-%d')
        #         conflict_order = Order.objects.filter(begin_date__lt=end_date, end_date__gt=start_date)
        #         # 开始时间在结束时间之后
        #         if sd >= ed:
        #             return JsonResponse({"errno": "4103", "errmsg": "参数错误"})
        #     # 只传了开始时间
        #     elif sd:
        #         start_date = datetime.datetime.strptime(sd, '%Y-%m-%d')
        #         conflict_order = Order.objects.filter(end_date__gt=start_date)
        #     # 只传了结束时间
        #     elif ed:
        #         start_date = datetime.datetime.today()
        #         end_date = datetime.datetime.strptime(ed, '%Y-%m-%d')
        #         conflict_order = Order.objects.filter(begin_date__lt=end_date, end_date__gt=start_date)
        #         # conflict_order = Order.objects.filter(begin_date__lt=end_date)
        #     # 不传时间，冲突订单列表为空
        #     else:
        #         conflict_order = []
        #
        # except Exception as e:
        #     return JsonResponse({"errno": "4103", "errmsg": "错误"})

        try:
            # 没有时间参数
            if not (sd and ed):
                start_date = datetime.datetime.today()
                end_date = start_date + datetime.timedelta(days=15)
                conflict_order = Order.objects.filter(begin_date__lt=start_date, end_date__gt=end_date)
            # 只传了结束时间
            elif ed and not sd:
                start_date = datetime.datetime.today()
                end_date = datetime.datetime.strptime(ed, '%Y-%m-%d')
                conflict_order = Order.objects.filter(begin_date__lt=end_date, end_date__gt=start_date)
            # 只传了开始时间
            elif sd and not ed:
                start_date = datetime.datetime.strptime(sd, '%Y-%m-%d')
                conflict_order = Order.objects.filter(end_date__gt=start_date)
            # 传入了开始和结束时间
            else:
                start_date = datetime.datetime.strptime(sd, '%Y-%m-%d')
                end_date = datetime.datetime.strptime(ed, '%Y-%m-%d')
                filters["min_days__lte"] = end_date - start_date
                filters["max_days__gte"] = end_date - start_date
                # 入住时间晚于结束时间
                if start_date > end_date:
                    start_date, end_date = end_date, start_date
                    conflict_order = Order.objects.filter(begin_date__lt=end_date, end_date__gt=start_date)
        except Exception as e:
            return JsonResponse({"errno": "4103", "errmsg": "错误"})

        # 将冲突订单的房屋id加入冲突列表
        conflict_house_id = []
        for order in conflict_order:
            conflict_house_id.append(order.house_id)
        # 排除自己的房子
        if user.is_authenticated:
            for house in House.objects.all():
                if user.id == house.user_id:
                    conflict_house_id.append(house.id)
        else:
            pass
        # 查询出来的房屋列表过滤冲突订单中的房屋id
        if conflict_house_id:
            filters["id__in"] = conflict_house_id

        houses_query = House.objects.filter(**filters).order_by(sk_dict.get(sk, "-create_time"))
        paginator = Paginator(houses_query, 5)
        # 获取当前页对象
        page_houses = paginator.page(p)
        # 获取总页数
        total_page = paginator.num_pages

        houses = []
        for house in page_houses:
            count = get_house_count_date(house, sd, ed)
            # 剩余房间数量为0,
            if count == 0:
                continue
            house_dict = {
                "address": house.address,
                "area_name": house.area.name,
                "ctime": house.create_time.strftime("%Y-%m-%d"),
                "house_id": house.id,
                "img_url": house.index_image_url if house.index_image_url else "",
                "order_count": house.order_count,
                "price": house.price,
                "room_count": get_house_count_date(house, sd, ed),
                "title": house.title,
                "user_avatar": 'http://127.0.0.1:8888/' + str(house.user.avatar) if 'http://127.0.0.1:8888/' + str(
                    house.user.avatar) else "",
            }
            houses.append(house_dict)

        data = {
            "total_page": total_page,
            "houses": houses
        }
        return JsonResponse({"errno": "0", "errmsg": "OK", "data": data})

    def post(self, request):

        # 1.获取登录用户
        user = request.user
        if not user.is_authenticated:
            return JsonResponse({
                'errno': "4101",
                'errmsg': '用户未登录'})

        # 2. 获取参数
        json_dict = json.loads(request.body.decode())
        title = json_dict.get('title')
        price = json_dict.get('price')
        area_id = json_dict.get('area_id')
        address = json_dict.get('address')
        room_count = json_dict.get('room_count')
        acreage = json_dict.get('acreage')
        unit = json_dict.get('unit')
        capacity = json_dict.get('capacity')
        beds = json_dict.get('beds')
        deposit = json_dict.get('deposit')
        min_days = json_dict.get('min_days')
        max_days = json_dict.get('max_days')
        facility = json_dict.get('facility')

        # 整体校验参数
        if not all([title, price, area_id, address, room_count, acreage, unit,
                    capacity, beds, deposit, min_days, max_days]):
            return JsonResponse({"errno": 4103,
                                 "errmsg": "参数错误"})

        # 单个检验(price,deposit)
        try:
            price = int(price) * 100
        except Exception as e:
            logger.error(e)
            return JsonResponse({"errno": 4103,
                                 "errmsg": "参数错误"})
        # deposit
        try:
            deposit = int(deposit) * 100
        except Exception as e:
            logger.error(e)
            return JsonResponse({"errno": 4103,
                                 'errmsg': '参数有误'})

        try:
            area = Area.objects.get(id=area_id)
        except Exception as e:
            logger.error(e)
            return JsonResponse({"errno": 4001,
                                 "errmsg": "数据库查询错误"})

        try:
            house = House.objects.create(user=user,
                                         title=title,
                                         price=price,
                                         area=area,
                                         room_count=room_count,
                                         address=address,
                                         acreage=acreage,
                                         unit=unit,
                                         capacity=capacity,
                                         beds=beds,
                                         deposit=deposit,
                                         min_days=min_days,
                                         max_days=max_days)

        except Exception as e:
            logger.error(e)
            return JsonResponse({"errno": 4004,
                                 "errmsg": "保存数据失败"})

        # 获取当前房屋的设备
        facilities = Facility.objects.filter(id__in=facility)
        house.facility.add(*facilities)

        try:
            house.save()
        except Exception as e:
            logger.error(e)
            return JsonResponse({"errno": 4004,
                                 "errmsg": "保存到数据库失败"})

        # 返回
        return JsonResponse({"errno": "0",
                             "errmsg": "发布成功",
                             "data": {"house_id": house.id}})


class ImageHousesView(View):
    '''上传房源图片'''

    def post(self, request, house_id):
        '''房屋图片上传 '''

        # 1. 取到上传的图片
        content = request.FILES.get('house_image')
        if content is None:
            return JsonResponse({'errno': 400, 'errmsg': "参数错误"})

        # 2. 查询房屋是否存在
        house = House.objects.get(id=house_id)

        # 3. 上传到Fdfs
        try:
            client = Fdfs_client(settings.FDFS_CLIENT_CONF)
            result = client.upload_by_buffer(content.read())
        except Exception as e:
            return JsonResponse({"errno": 4004,
                                 "errmsg": "上传图片错误"})

        # 4. 初始化房屋的图片模型
        # 上传成功：返回file_id,拼接图片访问URL
        file_id = result.get('Remote file_id')
        url = settings.FDFS_URL + file_id

        house_image = HouseImage.objects.create(house=house, url=url)

        # 判断是否有首页图片
        if not house.index_image_url:
            # 保存图片地址
            house.index_image_url = url
            house.save()

        # 返回
        return JsonResponse({'errno': 0, 'errmsg': "OK", 'data': {"url": url}})


class OrderCommitView(View):
    """提交订单"""

    def post(self, request):
        """保存订单信息"""

        # 1.获取登录用户
        user = request.user

        # 2.获取当前要保存的订单数据
        json_dict = json.loads(request.body.decode())
        house_id = json_dict.get('house_id')
        start_date = json_dict.get('start_date')
        end_date = json_dict.get('end_date')

        # 3.校验参数
        if not all([house_id, start_date, end_date]):
            return JsonResponse({'errno': 4004,
                                 'errmsg': '缺少必传参数'})

        # 4.获取入住天数
        datestart = datetime.datetime.strptime(start_date, '%Y-%m-%d')
        dateend = datetime.datetime.strptime(end_date, '%Y-%m-%d')
        if datestart < dateend:
            days = (dateend - datestart).days
        else:
            return JsonResponse({'errno': 4004,
                                 'errmsg': '入住时间选择有误'})

        # 5.获取房屋的信息
        try:
            house = House.objects.get(
                Q(id=house_id, max_days__gte=days, min_days__lte=days) | Q(id=house_id, max_days=0, min_days__lte=days))

        except Exception as e:

            return JsonResponse({'errno': 4004,
                                 'errmsg': '获取房屋信息错误'})

        # # 6.生成订单编号：年月日时分秒+用户编号
        # order_id = timezone.localtime().strftime('%Y%m%d%H%M%S') + ('%09d' % user.id)

        # 7.保存订单基本信息 Order
        try:
            order = Order.objects.create(
                house=house,
                user=user,
                begin_date=start_date,
                end_date=end_date,
                days=days,
                house_price=house.price,
                amount=days * house.price, )

        except Exception as e:
            logger.error(e)
            return JsonResponse({'errno': 4004,
                                 'errmsg': '生成订单失败'})
            # 8.返回

        return JsonResponse({"data": {"order_id": order.id},
                             "errno": "0",
                             "errmsg": "下单成功"})

    def get(self, request):
        '''获取订单列表'''
        # 1.获取登录用户
        user = request.user
        # 获取role参数
        role = request.GET.get("role")
        # 2.判断是 custom: 房客，landlord：房东

        if role is None:
            return JsonResponse({"erreno": 4004,
                                 "errmsg": "参数错误"})

        if role not in ('custom', "landlord"):
            return JsonResponse({"erreno": 4004,
                                 "errmsg": "参数错误"})

        order_list = []
        try:
            # 房客获取订单 ===> orders
            if role == "custom":
                orders = Order.objects.filter(user=user).order_by("-update_time")
                for order in orders:
                    time = str(order.create_time)[0:10]
                    order_list.append({
                        "amount": order.amount,
                        "comment": order.comment,
                        "ctime": time,
                        "days": order.days,
                        "start_date": order.begin_date,
                        "end_date": order.end_date,
                        "order_id": order.id,
                        "img_url": order.house.index_image_url,
                        "status": order.ORDER_STATUS_ENUM.get(order.status),
                        "title": order.house.title
                    })
            # 房东查询订单 ————> houses,orders,
            elif role == "landlord":
                # 获取房东的所有房屋: houses
                houses = House.objects.filter(user=user)

                for house in houses:
                    # 通过外键获取订单
                    orders = Order.objects.filter(house=house).order_by("-update_time")

                    for order in orders:
                        time = str(order.create_time)[0:10]
                        order_list.append({
                            "amount": order.amount,
                            "comment": order.comment,
                            "ctime": time,
                            "days": order.days,
                            "start_date": order.begin_date,
                            "end_date": order.end_date,
                            "order_id": order.id,
                            "img_url": order.house.index_image_url,
                            "status": order.ORDER_STATUS_ENUM.get(order.status),
                            "title": order.house.title})

            else:
                return JsonResponse({"errno": 4105,
                                     "errmsg": "用户身份错误"})

        except Exception as e:
            return JsonResponse({"erreno": 4001,
                                 "errmsg": "数据库获取参数错误"})

        return JsonResponse({'errno': 0,
                             'errmsg': "OK",
                             'data': {"orders": order_list}})
